package cn.bby.jtk.web.exception;

import cn.bby.jtk.base.exception.ServiceException;
import cn.bby.jtk.web.CommonResult;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;


/**
 * 全局异常，子组件再声明相同的异常捕获，可以覆盖
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 全局异常捕捉处理
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public CommonResult<Void> systemErrorHandler(HttpServletResponse response, Exception ex) {
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        log.error("SERVER_ERROR", ex);
        return CommonResult.error("SERVER_ERROR","系统错误");
    }

    /**
     * 校验 @RequestParam, @PathVariable, @RequestHeader, @CookieValue 等注解修饰的参数
     */
    @ResponseBody
    @ExceptionHandler(ConstraintViolationException.class)
    public CommonResult<Void> constraintViolationException(ConstraintViolationException ex, HttpServletResponse response) {
        log.info("PARAM_ERROR", ex);
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        return CommonResult.error("PARAM_ERROR",ex.getLocalizedMessage());
    }

    /**
     * 校验 @RequestBody 注解修饰的参数
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public CommonResult<Map<String, Object>> methodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletResponse response) {
        log.info("PARAM_ERROR", ex);
        Map<String, Object> errors = new HashMap<>();
        for (FieldError fieldError : ex.getFieldErrors()) {
            String msg = String.format("%s(%s)",fieldError.getDefaultMessage(),fieldError.getRejectedValue());
            errors.put(fieldError.getField(),msg);
        }
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        return CommonResult.error("PARAM_ERROR", errors);
    }
    /**
     * 全局异常捕捉处理
     */
    @ResponseBody
    @ExceptionHandler(value = ServiceException.class)
    public CommonResult<Void> serviceErrorHandler(HttpServletResponse response, ServiceException ex) {
        response.setStatus(ex.getHttpStatus());
        return CommonResult.error(ex.getCode(), ex.getLocalizedMessage());
    }
}
